# coding=utf-8
# author=haishan09@gmail.com
from __future__ import unicode_literals
from itertools import chain
from django.db import models
from custom.fields import  FontawesomeField
from guardian.models import UserObjectPermission


class MenuItem(models.Model):
    parent = models.ForeignKey('self', blank=True, null=True)
    label = models.CharField('标题', max_length=64)
    link = models.CharField('链接地址', default='#', max_length=512)
    level = models.IntegerField('等级')
    rank = models.IntegerField('序列')
    icon = FontawesomeField('图标', default='fa-chevron-circle-right', max_length=64)
    created_at = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return self.label

    class Meta:
        permissions = (
            ('view_menuitem', 'can see available menu items'),
        )

    def save(self, force_insert=False, **kwargs):
        if self.parent:
            if not self.level:
                self.level = self.parent.level + 1
            if not self.rank:
                self.rank = max([0, ] + [c.rank for c in self.parent.children]) + 1
        else:
            self.level = 0
            self.rank = 1
        super(MenuItem, self).save(force_insert, **kwargs)

    @property
    def flatten_children(self):
        flatten_list = [self, ]
        for child in self.children:
            flatten_list = chain(flatten_list, child.flatten_children)
        return flatten_list

    @property
    def children(self):
        return MenuItem.objects.filter(parent=self).order_by('rank')

    def has_children(self):
        return [c for c in self.children]

    def is_parent(self, menuitem_pk):
        return self.pk != menuitem_pk and menuitem_pk in [c.pk for c in self.flatten_children]

    @property
    def jstree_metadata(self):
        metadata = {
            'id': self.pk,
            'text': self.label,
            'state' : {'opened': True, 'selected': False},
            'icon': 'fa ' + self.icon,
            'children': []
        }
        for child in self.children:
            metadata['children'].append(child.jstree_metadata)
        return metadata

    def get_jstree_metadata_by_user(self, user):
        selected = user.has_perm('view_menuitem', self)
        metadata = {
            'id': self.pk,
            'text': self.label,
            'state' : {'opened': True, 'selected': selected},
            'icon': 'fa ' + self.icon,
            'children': []
        }
        for child in self.children:
            metadata['children'].append(child.get_jstree_metadata_by_user(user))
        return metadata

    def get_jstree_metadata_by_group(self, gid):
        return self.jstree_metadata

    def reset_level(self, level):
        self.level = level
        for c in self.children:
            c.reset_level(level + 1)
        self.save()

    def move_to(self, new_parent, rank):
        children = [c for c in new_parent.children if c.pk != self.pk]
        children.insert(rank, self)
        for i, c in enumerate(children):
            c.rank = i + 1
            c.save()
        self.parent = new_parent
        self.save()
        self.reset_level(new_parent.level + 1)

    def assign_perm(self, perm='view_menuitem', user=None):
        UserObjectPermission.objects.assign_perm(perm, user, obj=self)

    def remove_perm(self, perm='view_menuitem', user=None):
        UserObjectPermission.objects.remove_perm(perm, user, obj=self)
        for child in self.children:
            child.remove_perm(perm=perm, user=user)

class Menu(models.Model):
    root = models.ForeignKey(MenuItem)
    label = models.CharField('标题', max_length=64)
    created_at = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return self.label
